/*
 * $Id: TcpGate.cc,v 1.5 2006-04-16 04:44:51 bacon Exp $
 */

#include "Globals.h"
#include "TcpGate.h"
#include "GateProc.h"
#include "Command.h"
#include <xpp/bas/MutexLock.h>

TcpGate::TcpGate (const xp_char_t* name): Gate (name)
{
 	MutexLock lock (&app_env_mutex);
	setMaxConnections (app_env.gateMaxConnections());
}

int TcpGate::start (int flags)
{
        return Thread::start (flags);
}

int TcpGate::main ()
{
	XP_LOG1 (&app_log, name(), XP_LOG_INFO, 
		XP_TEXT("configured to listen on %s"), 
		(const xp_char_t*)binding_address.numericService());

	int err_code;
	if (TcpServer::start(&err_code) == -1)
	{
		XP_LOG0 (&app_log, name(), XP_LOG_CRITICAL,
			XP_TEXT("failed to start the service"));
		return -1;
	}

	return 0;
}

int TcpGate::stop ()
{
	return TcpServer::stop();
}

int TcpGate::handle_client (TcpSocket* sock, TcpAddress* addr)
{
	XP_LOG0 (&app_log, name(), XP_LOG_DEBUG,
		XP_TEXT("client connection established"));

	GateProc proc (sock, addr, this);

	SttpCmd cmd;
	while (!isStopRequested() && !proc.isExitRequested()) {
		if (proc.receiveCmd (&cmd) == -1) {
			if (proc.errorCode() == Sttp::ERR_RECEIVE) break;

			xp_char_t buf[100];
			xp_sprintf (
				buf, xp_countof(buf), XP_TEXT("%d"), proc.errorCode());
			const xp_char_t* err = proc.errorStr();
			proc.sendCmd (CMD_ERR, 2, buf, err);
			XP_LOG1 (&app_log, name(), XP_LOG_INFO,
				XP_TEXT("cmd reception error - %s"), err);
			break;
		}

		/* TODO: encryption
		{
			MutexLock ms (&gRunEnvMutex);
			AppEnv::EncMode encMode = app_env.encMode();
			if (encMode == AppEnv::ENC_ENABLED) proc.setOptEncSend (true);
			else if (encMode == AppEnv::END_DISABLED) proc.setOptEncSend (false);
			else proc.setOptEncSend (proc.optEncReceive());
		}
		*/

		if (proc.processCmd(cmd) == -1) {
			xp_char_t buf[100];
			xp_sprintf (buf, xp_countof(buf),
				XP_TEXT("%d"), proc.errorCode());
			
			const xp_char_t* err = proc.errorStr();
			proc.sendCmd (CMD_ERR, 2, buf, err);
			XP_LOG1 (&app_log, name(), XP_LOG_INFO,
				XP_TEXT("cmd processing error - %s"), err);
			break;
		}
	}

	XP_LOG0 (&app_log, name(), XP_LOG_DEBUG,
		XP_TEXT("client connection closed"));

	return 0;
}
